﻿using Arch.EntityFrameworkCore.UnitOfWork;
using AutoMapper;
using MyTodo.Api.Entities;
using MyTodo.Api.Services.Interfaces;
using MyTodo.Shared.Dtos;
using MyTodo.Shared.Parameters;
using MyTodo.Shared.Services;

namespace MyTodo.Api.Services;

/// <summary>
/// 待办事项存储服务实现
/// </summary>
public class ToDoService : IToDoService
{
    private readonly IUnitOfWork _unitOfWork;
    private readonly IMapper _mapper;

    public ToDoService(IUnitOfWork unitOfWork, IMapper mapper)
    {
        _unitOfWork = unitOfWork;
        _mapper = mapper;
    }

    public async Task<ApiResponse> AddAsync(ToDoDto model)
    {
        try
        {
            var dbTodo = _mapper.Map<ToDo>(model);
            dbTodo.CreateDate = DateTime.Now;
            dbTodo.UpdateDate = DateTime.Now;
            await _unitOfWork.GetRepository<ToDo>().InsertAsync(dbTodo);
            if (await _unitOfWork.SaveChangesAsync() > 0)
            {
                return new ApiResponse(true);
            }
            return new ApiResponse("添加数据失败");
        }
        catch (Exception ex)
        {

            return new ApiResponse(ex.Message);
        }
    }

    public async Task<ApiResponse> DeleteAsync(int id)
    {
        try
        {
            var repository = _unitOfWork.GetRepository<ToDo>();
            var todo = await repository.GetFirstOrDefaultAsync(predicate: e => e.Id.Equals(id));
            if (todo == null)
            {
                return new ApiResponse("删除失败，该数据不存在");
            }
            repository.Delete(todo);
            if (await _unitOfWork.SaveChangesAsync() > 0)
            {
                return new ApiResponse(true);
            }
            return new ApiResponse("删除数据失败");
        }
        catch (Exception ex)
        {

            return new ApiResponse(ex.Message);
        }
    }

    public async Task<ApiResponse> GetAllAsync(QueryParameter parameter)
    {
        try
        {
            var repository = _unitOfWork.GetRepository<ToDo>();
            var todos = await repository.GetPagedListAsync(
                predicate: x => string.IsNullOrWhiteSpace(parameter.Search) ?
                true : x.Title.Equals(parameter.Search),
                pageSize: parameter.PageSize,
                pageIndex: parameter.PageIndex,
                orderBy: source => source.OrderByDescending(x => x.CreateDate)
                );
            if (todos.TotalCount > 0)
            {
                return new ApiResponse(true, todos);
            }
            return new ApiResponse("获取数据失败");
        }
        catch (Exception ex)
        {

            return new ApiResponse(ex.Message);
        }
    }

    public async Task<ApiResponse> GetSingleAsync(int id)
    {
        try
        {
            var repository = _unitOfWork.GetRepository<ToDo>();
            var todo = await repository.GetFirstOrDefaultAsync(predicate: e => e.Id.Equals(id));
            if (todo != null)
            {
                return new ApiResponse(true, _mapper.Map<ToDoDto>(todo));
            }
            return new ApiResponse("查找失败");
        }
        catch (Exception ex)
        {

            return new ApiResponse(ex.Message);
        }
    }

    public async Task<ApiResponse> UpdateAsync(ToDoDto model)
    {
        try
        {
            var dbTodo = _mapper.Map<ToDo>(model);
            var repository = _unitOfWork.GetRepository<ToDo>();
            var todo = await repository.GetFirstOrDefaultAsync(predicate: e => e.Id.Equals(model.Id));
            if (todo == null)
            {
                throw new Exception("更新的数据未找到");
            }
            todo.Title = dbTodo.Title;
            todo.Content = dbTodo.Content;
            todo.Status = dbTodo.Status;
            todo.UpdateDate = DateTime.Now;

            repository.Update(todo);
            if (await _unitOfWork.SaveChangesAsync() > 0)
            {
                return new ApiResponse(true);
            }
            return new ApiResponse("更新数据异常");
        }
        catch (Exception ex)
        {

            return new ApiResponse(ex.Message);
        }
    }
}
